package cn.coufran.springboot.starter.log.logger;

import org.slf4j.event.Level;

/**
 * 日志记录器
 * @author Coufran
 * @version 1.0.0
 * @since 1.0.0
 */
public interface Logger {
    /**
     * 是否允许指定级别的日志
     * @param level 日志级别
     * @return 允许返回true
     */
    default boolean isLogEnabled(Level level) {
        switch (level) {
            case ERROR:
                return this.isErrorEnabled();
            case WARN:
                return this.isWarnEnabled();
            case INFO:
                return this.isInfoEnabled();
            case DEBUG:
                return this.isDebugEnabled();
            case TRACE:
                return this.isTraceEnabled();
            default:
                throw new IllegalStateException("level " + level + " is illegal");
        }
    }

    /**
     * 是否允许error级别的日志
     * @return 允许返回true
     */
    boolean isErrorEnabled();

    /**
     * 是否允许warn级别的日志
     * @return 允许返回true
     */
    boolean isWarnEnabled();

    /**
     * 是否允许info级别的日志
     * @return 允许返回true
     */
    boolean isInfoEnabled();

    /**
     * 是否允许debug级别的日志
     * @return 允许返回true
     */
    boolean isDebugEnabled();

    /**
     * 是否允许trace级别的日志
     * @return 允许返回true
     */
    boolean isTraceEnabled();

    /**
     * 输出指定级别的日志
     * @param level 日志级别
     * @param format 日志模版
     * @param arguments 插值
     */
    default void log(Level level, String format, Object... arguments) {
        switch (level) {
            case ERROR:
                this.error(format, arguments);
                return;
            case WARN:
                this.warn(format, arguments);
                return;
            case INFO:
                this.info(format, arguments);
                return;
            case DEBUG:
                this.debug(format, arguments);
                return;
            case TRACE:
                this.trace(format, arguments);
                return;
            default:
                throw new IllegalStateException("level " + level + " is illegal");
        }
    }

    /**
     * 输出error级别的日志
     * @param format 日志模版
     * @param arguments 插值
     */
    void error(String format, Object... arguments);

    /**
     * 输出warn级别的日志
     * @param format 日志模版
     * @param arguments 插值
     */
    void warn(String format, Object... arguments);

    /**
     * 输出info级别的日志
     * @param format 日志模版
     * @param arguments 插值
     */
    void info(String format, Object... arguments);

    /**
     * 输出debug级别的日志
     * @param format 日志模版
     * @param arguments 插值
     */
    void debug(String format, Object... arguments);

    /**
     * 输出trace级别的日志
     * @param format 日志模版
     * @param arguments 插值
     */
    void trace(String format, Object... arguments);

    /**
     * 输出指定级别的异常日志
     * @param level 指定级别
     * @param msg 日志消息
     * @param e 异常
     */
    default void log(Level level, String msg, Throwable e) {
        switch (level) {
            case ERROR:
                this.error(msg, e);
                return;
            case WARN:
                this.warn(msg, e);
                return;
            case INFO:
                this.info(msg, e);
                return;
            case DEBUG:
                this.debug(msg, e);
                return;
            case TRACE:
                this.trace(msg, e);
                return;
            default:
                throw new IllegalStateException("level " + level + " is illegal");
        }
    }

    /**
     * 输出error级别的异常日志
     * @param msg 日志消息
     * @param e 异常
     */
    void error(String msg, Throwable e);

    /**
     * 输出warn级别的异常日志
     * @param msg 日志消息
     * @param e 异常
     */
    void warn(String msg, Throwable e);

    /**
     * 输出info级别的异常日志
     * @param msg 日志消息
     * @param e 异常
     */
    void info(String msg, Throwable e);

    /**
     * 输出debug级别的异常日志
     * @param msg 日志消息
     * @param e 异常
     */
    void debug(String msg, Throwable e);

    /**
     * 输出trace级别的异常日志
     * @param msg 日志消息
     * @param e 异常
     */
    void trace(String msg, Throwable e);
}
